package com.yixun.qfbao.controller;

import com.alibaba.fastjson.JSONObject;
import com.yixun.qfbao.annotations.Domain;
import com.yixun.qfbao.annotations.EnumToMap;
import com.yixun.qfbao.api.service.WeAppMessageService;
import com.yixun.qfbao.apidto.LoginResDto;
import com.yixun.qfbao.apidto.UploadBase64ResDto;
import com.yixun.qfbao.config.FileConfig;
import com.yixun.qfbao.constants.ApiConstant;
import com.yixun.qfbao.dto.base.BaseResponseDTO;
import com.yixun.qfbao.hander.*;
import com.yixun.qfbao.model.dto.PartnerInfoDto;
import com.yixun.qfbao.service.WeappFormidService;
import com.yixun.qfbao.util.HttpServletUtil;
import com.yixun.qfbao.util.RedisUtil;
import com.yixun.qfbao.utils.HttpApi;
import com.yixun.qfbao.utils.JSONUtil;
import com.yixun.qfbao.utils.WeAppUtils;
import com.yixun.qfbao.vo.*;
import com.yixun.qfbao.xf.model.enums.ResultEnum;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@ResponseBody
@RequestMapping("/weapp")
public class WeAppController {

    private static final Logger logger = LoggerFactory.getLogger(WeAppController.class);

    @Autowired
    private LoginHander loginHander;
    @Autowired
    private GetPremisesCityGroupListHander getPremisesCityGroupListHander;
    @Autowired
    private GetAreaAndPremisesCountHander getAreaAndPremisesCountHander;
    @Autowired
    private GetAgentPremisesPageHander getAgentPremisesPageHander;
    @Autowired
    private GetAgentPremisesHistoryPageHander getAgentPremisesHistoryPageHander;
    @Autowired
    private AddReportHander addReportHander;
    @Autowired
    private GetReportModelListHander getReportModelListHander;
    @Autowired
    private GetCPPageHander getCPPageHander;
    @Autowired
    private GetCPDetailHander getCPDetailHander;
    @Autowired
    private GetReportModelInfoListHander getReportModelInfoListHander;
    @Autowired
    private AddFollowHander addFollowHander;
    @Autowired
    private CreateQRCodeHander createQRCodeHander;
    @Autowired
    private FileConfig fileConfig;
    @Autowired
    private AddAppealHander addAppealHander;
    @Autowired
    private GetAgentPremisesDynamicPageHander getAgentPremisesDynamicPageHander;
    @Autowired
    private GetPerCPCommissionListHander getPerCPCommissionListHander;
    @Autowired
    private GetParentDeptHander getParentDeptHander;
    @Autowired
    private GetCustomerPremisesHander getCustomerPremisesHander;
    @Autowired
    private GetHasCPcusListHander getHasCPcusListHander;
    @Autowired
    private GetPremisesGroupByCityHander getPremisesGroupByCityHander;
    @Autowired
    private GetCustomerPremisesWeAppHander getCustomerPremisesWeAppHander;
    @Autowired
    private GetPremisesDynamicDetailHander getPremisesDynamicDetailHander;
    @Autowired
    private GetPremisesDynamicHander getPremisesDynamicHander;
    @Autowired
    private GetPremisesDetailHander getPremisesDetailHander;
    @Autowired
    private UpdatePwdHander updatePwdHander;
    @Autowired
    private RegistHander registHander;
    @Autowired
    private SendVerificationCodeHander sendVerificationCodeHander;
    @Autowired
    private SendValidateCodeForPwdHander sendValidateCodeForPwdHander;
    @Autowired
    private GetDeptByCompCodeHander getDeptByCompCodeHander;
    @Autowired
    private ForgetPwdHander forgetPwdHander;
    @Autowired
    private EditCPCusInfoHander editCPCusInfoHander;
    @Autowired
    private GetCompanyInfoHander getCompanyInfoHander;
    @Autowired
    private SearchCount4CustomerAndPremisesHander searchCount4CustomerAndPremisesHander;
    @Autowired
    private AddRecommendCompanyHander addRecommendCompanyHander;
    @Autowired
    private WeAppMessageService weAppMessageService;
    @Autowired
    private AddWeAppFormIdHander addWeAppFormIdHander;
    @Autowired
    private GetCPFollowStatusListHander getCPFollowStatusListHander;
    @Autowired
    private WeappFormidService weappFormidService;

    @PostMapping(value = "/login", produces = "application/json")
    public String login(@RequestBody LoginReqVo reqVo) {
        try {
            BaseResponseDTO<LoginResDto> result = loginHander.hander(reqVo);
            return JSONUtil.toJSONStringWithDateFormat(result);
        } catch (Exception e) {
            logger.error("login error: {}", e);
        }
        return null;
    }

    @PostMapping(value = "/getPremisesCityGroupList", produces = "application/json")
    public String getPremisesCityGroupList(HttpServletRequest request,@RequestBody GetPremisesCityGroupListReqVo getPremisesCityGroupListReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPremisesCityGroupListHander.hander(getPremisesCityGroupListReqVo));
        } catch (Exception e) {
            logger.error("getPremisesCityGroupList error: {}", e);
        }
        return null;
    }

    /**
     * 获取市区列表（含该区楼盘统计）
     */
    @Domain
    @PostMapping(value = "/getAreaAndPremisesCount", produces = "application/json")
    public String getAreaAndPremisesCount(HttpServletRequest request, @RequestBody GetAreaAndPremisesCountReqVo getAreaAndPremisesCountReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getAreaAndPremisesCountHander.hander(getAreaAndPremisesCountReqVo));
        } catch (Exception e) {
            logger.error("getAreaAndPremisesCount error: {}", e);
        }
        return null;
    }
    /**
     * （4） 楼盘列表
     */
    @Domain
    @PostMapping(value = "/getAgentPremisesPage", produces = "application/json")
    public String getAgentPremisesPage(HttpServletRequest request, @RequestBody GetAgentPremisesPageReqVo findPremisesListReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getAgentPremisesPageHander.hander(findPremisesListReqVo));
        } catch (Exception e) {
            logger.error("getAgentPremisesPage error: {}", e);
            return null;
        }
    }
    /**
     * 楼盘列表
     */
    @Domain
    @PostMapping(value = "/getAgentPremisesHistoryPage", produces = "application/json")
    public String getAgentPremisesHistoryPage(HttpServletRequest request, @RequestBody GetAgentPremisesPageReqVo findPremisesListReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getAgentPremisesHistoryPageHander.hander(findPremisesListReqVo));
        } catch (Exception e) {
            logger.error("getAgentPremisesPage error: {}", e);
            return null;
        }
    }

    /**
     * 新增报备
     */
    @Domain
    @PostMapping(value = "/addReport", produces = "application/json")
    public String addReport(HttpServletRequest request, @RequestBody AddReportReqVo addReportReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(addReportHander.doBusiness(addReportReqVo));
        } catch (Exception e) {
            logger.error("weApp addReport error: ", e);
            return null;
        }
    }

    /**
     * 获取报备列表
     */
    @Domain
    @PostMapping(value = "/getCPPage")
    public String getCPPage(HttpServletRequest request, @RequestBody GetCPPageReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getCPPageHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("weApp getCPPage error: {}", e);
            return null;
        }
    }

    @EnumToMap
    @SuppressWarnings("unchecked")
    @GetMapping("/getEnum/{key}")
    public Map<Object, String> getEnum(HttpServletRequest request, @PathVariable("key") String key) {
        return (Map<Object, String>)request.getAttribute(ApiConstant.ENUMMAP);
    }

    @PostMapping(value = "/getCPDetail", produces = "application/json")
    public String getCPDetail(HttpServletRequest request, @RequestBody GetCPDetailReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getCPDetailHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getCPDetail error: {}", e);
            return null;
        }
    }

    //获取报备模板详细信息
    @PostMapping(value="/getReportModelInfoList")
    public String getReportModelInfoList(@RequestBody GetReportModelInfoListReqVo reqVo) {
        return JSONUtil.toJSONStringWithDateFormat(getReportModelInfoListHander.hander(reqVo));
    }

    @PostMapping(value = "/addFollow", produces = "application/json")
    @Domain
    public String addFollow(HttpServletRequest request, @RequestBody AddFollowReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(addFollowHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("addFollow error: {}", e);
            return null;
        }
    }

    /**
     * （2） 生成二维码
     */
    @Domain
    @PostMapping(value = "/createQRCode", produces = "application/json")
    public String createQRCode(HttpServletRequest request, @RequestBody CreateQRCodeReqVo createQRCodeReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(createQRCodeHander.hander(createQRCodeReqVo));
        } catch (Exception e) {
            logger.error("createQRCode error: {}", e);
            return null;
        }
    }


    /**
     * 上传图片
     *
     * @param mulRequest
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/uploadBase64", produces = "application/json")
    public String uploadBase64(MultipartHttpServletRequest mulRequest) {
        BaseResponseDTO<UploadBase64ResDto> res = new BaseResponseDTO<>();
        UploadBase64ResDto resDto = new UploadBase64ResDto();
        try {
            Iterator<String> fileNames = mulRequest.getFileNames();
            byte[] imgByte = null;
            // 遍历请求中的图片信息
            if (fileNames.hasNext()) {
                // 图片对应的参数名
                String fileName = fileNames.next();
                // 获取到图片
                MultipartFile file = mulRequest.getFile(fileName);
                if (file != null) {
                    logger.info("upload file,file set {}", fileConfig.getFileSet());
                    String result = HttpApi.doPostForFile(file,fileConfig.getFileSet());
                    logger.info("upload file,result {}", result);
                    if(result != null ){
                        return result;
                    }
                    // 可以获取到图片的字节数组
                    imgByte = file.getBytes();
                }
            }
        } catch (Exception e) {
            logger.error("上传图片失败: {}", e);
            res.setResult(ResultEnum.FAIL.getNo());
            res.setErrorMsg("上传图片失败");
        }
        return JSONUtil.toJSONStringWithDateFormat(res);
    }

    /**
     * 经纪人发起申诉
     */
    @Domain
    @PostMapping(value = "/addAppeal", produces = "application/json")
    public String addAppeal(HttpServletRequest request, @RequestBody AddAppealReqVo addAppealReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(addAppealHander.hander(addAppealReqVo));
        } catch (Exception e) {
            logger.error("addAppeal error: {}", e);
        }
        return null;
    }

    @Domain
    @PostMapping(value = "/getAgentPremisesDynamicPage", produces = "application/json")
    public String getAgentPremisesDynamicPage(HttpServletRequest request, @RequestBody GetAgentPremisesDynamicPageReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getAgentPremisesDynamicPageHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getAgentPremisesDynamicPage error: {}", e);
        }
        return null;
    }

    /**
     * 获取个人报备佣金列表
     *
     * @return
     */
    @PostMapping(value = "/getPerCPCommissionList", produces = "application/json")
    public String getPerCPCommissionList(@RequestBody GetPerCPCommissionListReqVo getPerCPCommissionListReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPerCPCommissionListHander.hander(getPerCPCommissionListReqVo));
        } catch (Exception e) {
            logger.error("getPerCPCommissionList error: {}", e);
        }
        return null;
    }

    /**
     * 获取部门关系（分销助手）
     */
    @PostMapping(value = "/getParentDept", produces = "application/json")
    @Domain
    public String getParentDept(@RequestBody GetParentDeptReqVo reqVo,HttpServletRequest request) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getParentDeptHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getParentDept error: {}", e);
            return null;
        }
    }

    /**
     * @description 首页统计
     **/
    @Domain
    @PostMapping("/getCustomerPremises")
    public String getCustomerPremises(HttpServletRequest request, @RequestBody GetCustomerPremisesReqVo getCustomerPremisesReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getCustomerPremisesWeAppHander.hander(getCustomerPremisesReqVo));
        } catch (Exception e) {
            logger.error("getCustomerPremises error: {}", e);
        }
        return null;
    }

    /**
     * 获取报备模板列表
     */
    @ApiOperation(value="获取报备模板列表")
    @PostMapping(value="/getReportModelList")
    public String getReportModelList(@RequestBody GetReportModelListReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getReportModelListHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("weApp getReportModelList error: {}", e);
            return  null;
        }
    }

    /**
     * 楼盘动态详情
     */
    @Domain
    @PostMapping(value = "/getPremisesDynamicDetail", produces = "application/json")
    public String getPremisesDynamicDetail(HttpServletRequest request, @RequestBody GetPremisesDynamicDetailReqVo getPremisesDynamicDetailReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPremisesDynamicDetailHander.hander(getPremisesDynamicDetailReqVo));
        } catch (Exception e) {
            logger.error("getPremisesDynamicDetail error: {}", e);
            return null;
        }
    }

    /**
     * 获取已报备的楼盘用户列表
     */
    @PostMapping(value = "/getHasCPcusList", produces = "application/json")
    public String getHasCPcusList(@RequestBody GetHasCPcusListReqVo getHasCPcusListReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getHasCPcusListHander.hander(getHasCPcusListReqVo));
        } catch (Exception e) {
            logger.error("getHasCPcusList error: {}", e);
            return null;
        }
    }

    /**
     * 获得楼盘动态
     */
    @PostMapping(value = "/getPremisesDynamicList", produces = "application/json")
    public String getPremisesDynamic(@RequestBody GetPremisesDynamicReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPremisesDynamicHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getPremisesDynamicList error: {}", e);
            return null;
        }
    }

    /**
     * 楼盘详情
     */
    @Domain
    @PostMapping(value = "/getPremisesDetail", produces = "application/json")
    public String getPremisesDetail(HttpServletRequest request, @RequestBody GetPremisesDetailReqVo getPremisesDetailReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPremisesDetailHander.hander(getPremisesDetailReqVo));
        } catch (Exception e) {
            logger.error("getPremisesDetail error: {}", e);
            return null;
        }
    }

    /**
     * @Description 修改密码
     **/
    @Domain
    @PostMapping("/updatePwd")
    public String updatePwd(HttpServletRequest request, @RequestBody UpdatePwdReqVo updatePwdReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(updatePwdHander.hander(updatePwdReqVo));
        } catch (Exception e) {
            logger.error("updatePwd error: {}", e);
            return null;
        }
    }

    /**
     * 新用户注册
     */
    //todo 修改原先代码 测试需要测试原先方法
    @PostMapping(value = "/regist", produces = "application/json")
    public String regist(HttpServletRequest request, @RequestBody RegistReqVo registReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(registHander.hander(registReqVo));
        } catch (Exception e) {
            logger.error("regist error: {}", e);
            return null;
        }
    }

    /**
     * 获取楼盘所在城市
     */
    @Domain
    @PostMapping(value = "/getPremisesGroupByCity", produces = "application/json")
    public String getPremisesGroupByCity(HttpServletRequest request, @RequestBody GetPremisesGroupByCityReqVo getPremisesGroupByCityReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getPremisesGroupByCityHander.hander(getPremisesGroupByCityReqVo));
        } catch (Exception e) {
            logger.error("getPremisesGroupByCity error: {}", e);
            return null;
        }
    }

    /**
     * 发送注册验证码
     */
    @PostMapping(value = "/sendVerificationCode", produces = "application/json")
    public String sendVerificationCode(HttpServletRequest request, @RequestBody SendVerificationCodeReqVo sendVerificationCodeReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(sendVerificationCodeHander.hander(sendVerificationCodeReqVo));
        } catch (Exception e) {
            logger.error("sendVerificationCode error: {}", e);
        }
        return null;
    }

    /**
     * 发送重置验证码的短信
     **/
    @PostMapping(value = "/sendValidateCodeForPwd", produces = "application/json")
    public String sendValidateCodeForPwd(HttpServletRequest request, @RequestBody SendValidateCodeForPwdReqVo sendValidateCodeForPwdReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(sendValidateCodeForPwdHander.hander(sendValidateCodeForPwdReqVo));
        } catch (Exception e) {
            logger.error("sendValidateCodeForPwd error: {}", e);
        }
        return null;
    }

    /**
     * @description 合并部门
     **/
    @PostMapping(value = "/getDeptByCompCode", produces = "application/json")
    public String getDeptByCompCode(HttpServletRequest request, @RequestBody GetDeptByCompCodeReqVo reqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getDeptByCompCodeHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getDeptByCompCode error: {}", e);
        }
        return null;
    }

    /**
     * 忘记密码
     **/
    @Domain
    @PostMapping("/forgetPwd")
    public String resetPwd(HttpServletRequest request, @RequestBody ForgetPwdReqVo forgetPwdReqVo) {
        try {
            return JSONUtil.toJSONStringWithDateFormat(forgetPwdHander.hander(forgetPwdReqVo));
        } catch (Exception e) {
            logger.error("resetPwd error: {}", e);
            return null;
        }
    }

    @PostMapping(value = "/editCPCusInfo", produces = "application/json")
    public String editCPCusInfo(HttpServletRequest request, @RequestBody EditCPCusInfoReqVo reqVo)
            throws IOException {
        try {
            return JSONUtil.toJSONStringWithDateFormat(editCPCusInfoHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("editCPCusInfo error: {}", e);
            return null;
        }
    }

    @PostMapping(value = "/getCompanyInfo", produces = "application/json")
    public String getCompanyInfo(@RequestBody GetCompanyInfoReqVo requestVo,HttpServletRequest request){
        try{
            return JSONUtil.toJSONStringWithDateFormat(getCompanyInfoHander.hander(requestVo));
        }catch (Exception e){
            logger.error("GetCompanyInfo error: {}", e);
            return null;
        }
    }

    @PostMapping(value = "/searchCount4CustomerAndPremises", produces = "application/json")
    @Domain
    public String searchCount4CustomerAndPremises(@RequestBody SearchCount4CustomerAndPremisesReqVo requestVo,HttpServletRequest request){
        try{
            return JSONUtil.toJSONStringWithDateFormat(searchCount4CustomerAndPremisesHander.hander(requestVo));
        }catch (Exception e){
            logger.error("searchCount4CustomerAndPremises error: {}", e);
            return null;
        }
    }


    @PostMapping(value = "/addRecommendCompany", produces = "application/json")
    @Domain
    public String addRecommendCompany(@RequestBody AddRecommendCompanyReqVo requestVo,HttpServletRequest request){
        try{
            return JSONUtil.toJSONStringWithDateFormat(addRecommendCompanyHander.hander(requestVo));
        }catch (Exception e){
            logger.error("addRecommendCompany error: {}", e);
            return null;
        }
    }

    @PostMapping(value = "/collectFormId")
    public String collectFormId(@RequestBody AddWeAppFormIdReqVo requestVo) {
        return JSONUtil.toJSONStringWithDateFormat(addWeAppFormIdHander.hander(requestVo));
    }

    /**
     * 微信服务器校验接口
     * @return
     */
    @RequestMapping(value = "/message/check", method= {RequestMethod.GET, RequestMethod.POST})
    public String check(){
        HttpServletRequest request = HttpServletUtil.getRequest();
        //微信加密签名
        String signature = request.getParameter("signature");
        //时间戳
        String timestamp = request.getParameter("timestamp");
        //随机数
        String nonce = request.getParameter("nonce");
        //随机字符串
        String echostr = request.getParameter("echostr");
        logger.info("check request params:", "signature ==> " + signature + ",timestamp ==>" + timestamp + ",nonce ==>" + nonce + ",echostr ==>" + echostr);
        logger.info("weAppMessageService:", (null == weAppMessageService));
        return weAppMessageService.check(signature, timestamp, nonce, echostr);
    }

    @PostMapping(value = "/getCPFollowStatusList", produces = "application/json")
    public String getCPFollowStatusList(HttpServletRequest request, HttpServletResponse response, @RequestBody GetCPFollowStatusListReqVo reqVo)
            throws IOException {
        try {
            return JSONUtil.toJSONStringWithDateFormat(getCPFollowStatusListHander.hander(reqVo));
        } catch (Exception e) {
            logger.error("getCPFollowStatusList error: {}", e);
            return null;
        }
    }

    @PostMapping(value = "/cleanFormid", produces = "application/json")
    public String cleanFormid() {
        try {
            weappFormidService.cleanFormID();
            return "clean weapp formids success";
        } catch (Exception e) {
            logger.error("cleanFormid error: {}", e);
            return "clean weapp formids failure";
        }
    }
}

